home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Comunicatii / htttrack / httrack-3.32-2.exe / {app} / src / minizip / mztools.c < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-08  |  7.9 KB  |  287 lines

  1. /*
  2.   Additional tools for Minizip
  3.   Code: Xavier Roche '2004
  4.   License: Same as ZLIB (www.gzip.org)
  5. */
  6.  
  7. /* Code */
  8. #include <string.h>
  9. #ifndef _WIN32_WCE
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #else
  13. #include <stdio.h>
  14. //#include "celib.h"
  15. #endif
  16. #include "zlib.h"
  17. #include "unzip.h"
  18.  
  19. #define READ_8(adr)  ((unsigned char)*(adr))
  20. #define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
  21. #define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
  22.  
  23. #define WRITE_8(buff, n) do { \
  24.   *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
  25. } while(0)
  26. #define WRITE_16(buff, n) do { \
  27.   WRITE_8((unsigned char*)(buff), n); \
  28.   WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
  29. } while(0)
  30. #define WRITE_32(buff, n) do { \
  31.   WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
  32.   WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
  33. } while(0)
  34.  
  35. extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
  36. const char* file;
  37. const char* fileOut;
  38. const char* fileOutTmp;
  39. uLong* nRecovered;
  40. uLong* bytesRecovered;
  41. {
  42.   int err = Z_OK;
  43.   FILE* fpZip = fopen(file, "rb");
  44.   FILE* fpOut = fopen(fileOut, "wb");
  45.   FILE* fpOutCD = fopen(fileOutTmp, "wb");
  46.   if (fpZip != NULL &&  fpOut != NULL) {
  47.     int entries = 0;
  48.     uLong totalBytes = 0;
  49.     char header[30];
  50.     char filename[256];
  51.     char extra[1024];
  52.     int offset = 0;
  53.     int offsetCD = 0;
  54.     while ( fread(header, 1, 30, fpZip) == 30 ) {
  55.       int currentOffset = offset;
  56.  
  57.       /* File entry */
  58.       if (READ_32(header) == 0x04034b50) {
  59.         unsigned int version = READ_16(header + 4);
  60.         unsigned int gpflag = READ_16(header + 6);
  61.         unsigned int method = READ_16(header + 8);
  62.         unsigned int filetime = READ_16(header + 10);
  63.         unsigned int filedate = READ_16(header + 12);
  64.         unsigned int crc = READ_32(header + 14); /* crc */
  65.         unsigned int cpsize = READ_32(header + 18); /* compressed size */
  66.         unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
  67.         unsigned int fnsize = READ_16(header + 26); /* file name length */
  68.         unsigned int extsize = READ_16(header + 28); /* extra field length */
  69.         filename[0] = extra[0] = '\0';
  70.         
  71.         /* Header */
  72.         if (fwrite(header, 1, 30, fpOut) == 30) {
  73.           offset += 30;
  74.         } else {
  75.           err = Z_ERRNO;
  76.           break;
  77.         }
  78.         
  79.         /* Filename */
  80.         if (fnsize > 0) {
  81.           if (fread(filename, 1, fnsize, fpZip) == fnsize) {
  82.             if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
  83.               offset += fnsize;
  84.             } else {
  85.               err = Z_ERRNO;
  86.               break;
  87.             }
  88.           } else {
  89.             err = Z_ERRNO;
  90.             break;
  91.           }
  92.         } else {
  93.           err = Z_STREAM_ERROR;
  94.           break;
  95.         }
  96.  
  97.         /* Extra field */
  98.         if (extsize > 0) {
  99.           if (fread(extra, 1, extsize, fpZip) == extsize) {
  100.             if (fwrite(extra, 1, extsize, fpOut) == extsize) {
  101.               offset += extsize;
  102.             } else {
  103.               err = Z_ERRNO;
  104.               break;
  105.             }
  106.           } else {
  107.             err = Z_ERRNO;
  108.             break;
  109.           }
  110.         }
  111.         
  112.         /* Data */
  113.         {
  114.           int dataSize = cpsize;
  115.           if (dataSize == 0) {
  116.             dataSize = uncpsize;
  117.           }
  118.           if (dataSize > 0) {
  119.             char* data = malloc(dataSize);
  120.             if (data != NULL) {
  121.               if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
  122.                 if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
  123.                   offset += dataSize;
  124.                   totalBytes += dataSize;
  125.                 } else {
  126.                   err = Z_ERRNO;
  127.                 }
  128.               } else {
  129.                 err = Z_ERRNO;
  130.               }
  131.               free(data);
  132.               if (err != Z_OK) {
  133.                 break;
  134.               }
  135.             } else {
  136.               err = Z_MEM_ERROR;
  137.               break;
  138.             }
  139.           }
  140.         }
  141.         
  142.         /* Central directory entry */
  143.         {
  144.           char header[46];
  145.           char* comment = "";
  146.           int comsize = (int) strlen(comment);
  147.           WRITE_32(header, 0x02014b50);
  148.           WRITE_16(header + 4, version);
  149.           WRITE_16(header + 6, version);
  150.           WRITE_16(header + 8, gpflag);
  151.           WRITE_16(header + 10, method);
  152.           WRITE_16(header + 12, filetime);
  153.           WRITE_16(header + 14, filedate);
  154.           WRITE_32(header + 16, crc);
  155.           WRITE_32(header + 20, cpsize);
  156.           WRITE_32(header + 24, uncpsize);
  157.           WRITE_16(header + 28, fnsize);
  158.           WRITE_16(header + 30, extsize);
  159.           WRITE_16(header + 32, comsize);
  160.           WRITE_16(header + 34, 0);     /* disk # */
  161.           WRITE_16(header + 36, 0);     /* int attrb */
  162.           WRITE_32(header + 38, 0);     /* ext attrb */
  163.           WRITE_32(header + 42, currentOffset);
  164.           /* Header */
  165.           if (fwrite(header, 1, 46, fpOutCD) == 46) {
  166.             offsetCD += 46;
  167.             
  168.             /* Filename */
  169.             if (fnsize > 0) {
  170.               if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
  171.                 offsetCD += fnsize;
  172.               } else {
  173.                 err = Z_ERRNO;
  174.                 break;
  175.               }
  176.             } else {
  177.               err = Z_STREAM_ERROR;
  178.               break;
  179.             }
  180.             
  181.             /* Extra field */
  182.             if (extsize > 0) {
  183.               if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
  184.                 offsetCD += extsize;
  185.               } else {
  186.                 err = Z_ERRNO;
  187.                 break;
  188.               }
  189.             }
  190.             
  191.             /* Comment field */
  192.             if (comsize > 0) {
  193.               if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
  194.                 offsetCD += comsize;
  195.               } else {
  196.                 err = Z_ERRNO;
  197.                 break;
  198.               }
  199.             }
  200.             
  201.             
  202.           } else {
  203.             err = Z_ERRNO;
  204.             break;
  205.           }
  206.         }
  207.  
  208.         /* Success */
  209.         entries++;
  210.  
  211.       } else {
  212.         break;
  213.       }
  214.     }
  215.  
  216.     /* Final central directory  */
  217.     {
  218.       int entriesZip = entries;
  219.       char header[22];
  220.       char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
  221.       int comsize = (int) strlen(comment);
  222.       if (entriesZip > 0xffff) {
  223.         entriesZip = 0xffff;
  224.       }
  225.       WRITE_32(header, 0x06054b50);
  226.       WRITE_16(header + 4, 0);    /* disk # */
  227.       WRITE_16(header + 6, 0);    /* disk # */
  228.       WRITE_16(header + 8, entriesZip);   /* hack */
  229.       WRITE_16(header + 10, entriesZip);  /* hack */
  230.       WRITE_32(header + 12, offsetCD);    /* size of CD */
  231.       WRITE_32(header + 16, offset);      /* offset to CD */
  232.       WRITE_16(header + 20, comsize);     /* comment */
  233.       
  234.       /* Header */
  235.       if (fwrite(header, 1, 22, fpOutCD) == 22) {
  236.         
  237.         /* Comment field */
  238.         if (comsize > 0) {
  239.           if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
  240.             err = Z_ERRNO;
  241.           }
  242.         }
  243.         
  244.       } else {
  245.         err = Z_ERRNO;
  246.       }
  247.     }
  248.  
  249.     /* Final merge (file + central directory) */
  250.     fclose(fpOutCD);
  251.     if (err == Z_OK) {
  252.       fpOutCD = fopen(fileOutTmp, "rb");
  253.       if (fpOutCD != NULL) {
  254.         int nRead;
  255.         char buffer[8192];
  256.         while ( (nRead = fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
  257.           if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
  258.             err = Z_ERRNO;
  259.             break;
  260.           }
  261.         }
  262.         fclose(fpOutCD);
  263.       }
  264.     }
  265.     
  266.     /* Close */
  267.     fclose(fpZip);
  268.     fclose(fpOut);
  269.     
  270.     /* Wipe temporary file */
  271.     (void)remove(fileOutTmp);
  272.     
  273.     /* Number of recovered entries */
  274.     if (err == Z_OK) {
  275.       if (nRecovered != NULL) {
  276.         *nRecovered = entries;
  277.       }
  278.       if (bytesRecovered != NULL) {
  279.         *bytesRecovered = totalBytes;
  280.       }
  281.     }
  282.   } else {
  283.     err = Z_STREAM_ERROR;
  284.   }
  285.   return err;
  286. }
  287.